<?php
/**
 * Logger.php
 *
 * 日志类
 *
 * @copyright   2023 thingsworld.com.cn - All Rights Reserved
 * @link        http://thingsworld.com.cn/
 * @author      stiffer.chen <chenl@thingsworld.com.cn>
 * @created     2023-02-14 15:14:31
 * @modified    2023-02-14 15:14:31
 *
 */

namespace App\Library;

use Illuminate\Support\Str;
use Monolog\Logger as MonoLogger;
use Monolog\Handler\StreamHandler;
use Monolog\Formatter\LineFormatter;

class Logger
{
    private $log;

    const FREQUENTLY_DAY = 'day';
    const FREQUENTLY_MONTH = 'month';
    const FREQUENTLY_YEAR = 'year';

    public function __construct(string $name, $frequently = self::FREQUENTLY_DAY)
    {
        $this->log = new MonoLogger(Str::camel($name));
        $fileName = $this->getLogName($name, $frequently);
        $logFile = storage_path() . '/logs/' . $fileName . '.log';
        $level = config('app.log_level', MonoLogger::DEBUG);

        $handler = new StreamHandler($logFile, $level, true, 0777);
        $lineFormatter = new LineFormatter("[%datetime%] %channel%.%level_name%: %message%\n");
        $handler->setFormatter($lineFormatter);
        $this->log->pushHandler($handler);
    }

    private function getLogName(string $logName, string $frequently)
    {
        $frequently = strtolower($frequently);
        if ($frequently == self::FREQUENTLY_DAY) {
            $fileName = Str::snake($logName) . DIRECTORY_SEPARATOR . date('Ymd');
        } elseif ($frequently == self::FREQUENTLY_MONTH) {
            $fileName = Str::snake($logName) . DIRECTORY_SEPARATOR . date('Ym');
        } elseif ($frequently == self::FREQUENTLY_YEAR) {
            $fileName = Str::snake($logName) . DIRECTORY_SEPARATOR . date('Y');
        } else {
            $fileName = Str::snake($logName);
        }
        return $fileName;
    }

    private function handleMessage($message)
    {
        if (PHP_SAPI == 'cli' && app()->environment() !== 'testing') {
            d($message);
        }

        if (!is_string($message)) {
            return json_encode($message);
        }

        return $message;
    }

    public function error(...$message)
    {
        foreach ($message as $item) {
            $this->log->error($this->handleMessage($item));
        }
    }

    public function warning(...$message)
    {
        foreach ($message as $item) {
            $this->log->warning($this->handleMessage($item));
        }
    }

    public function notice(...$message)
    {
        foreach ($message as $item) {
            $this->log->notice($this->handleMessage($item));
        }
    }

    public function info(...$message)
    {
        foreach ($message as $item) {
            $this->log->info($this->handleMessage($item));
        }
    }

    public function debug(...$message)
    {
        foreach ($message as $item) {
            $this->log->debug($this->handleMessage($item));
        }
    }
}